﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Data;

namespace TJ_MainNameSpace
{
    class CurveMaker
    {
        private Graphics objGraphics; //Graphics 类提供将对象绘制到显示设备的方法
        private Bitmap objBitmap; //位图对象

        private int m_Width = 900; //图像宽度
        private int m_Height = 500; //图像高度
        private float m_XSlice = 50; //X轴刻度宽度
        private float m_YSlice = 50; //Y轴刻度宽度
        private float m_YSliceValue = 20; //Y轴刻度的数值宽度
        private float m_YSliceBegin = 0; //Y轴刻度开始值
        private int m_XSliceValue = 0;//X轴刻度的数值宽度
        private long m_XSliceBegin = 0;//X轴刻度开始值
        private float m_Tension = 0.0f;
        private string m_Title = ""; //Title
        private string m_Unit = ""; //单位
        private string m_XAxisText = ""; //X轴说明文字
        private string m_YAxisText = ""; //Y轴说明文字
        private string m_CurveName = "";//曲线名称
        private string[] m_Keys = null;//X轴时间的字符串形式
        private long[] m_KeyValues = null;//X轴时间的秒值形式
        private float[] m_Values = null;
        private Color m_BgColor = Color.Black; //背景
        private Color m_TextColor = Color.Snow; //文字颜色
        private Color m_BorderColor = Color.Black; //整体边框颜色
        private Color m_AxisColor = Color.Snow; //轴线颜色
        private Color m_AxisTextColor = Color.Black; //轴说明文字颜色
        private Color m_SliceTextColor = Color.Snow; //刻度文字颜色
        private Color m_SliceColor = Color.Snow; //刻度颜色
        private Color m_CurveColor = Color.Red; //曲线颜色
        private Point m_TempCurveName;//临时存储曲线名称的坐标
        private float m_CurveWidth = 0.0f;//曲线宽度
        private CurveOption m_CO;//曲线绘制选项

        #region 属性区
        public Bitmap BMP
        {
            get
            {
                return objBitmap;
            }
        }

        public int Width
        {
            set
            {
                if (value < 300)
                {
                    m_Width = 300;
                }
                else
                {
                    m_Width = value;
                }
            }
            get
            {
                return m_Width;
            }
        }

        public int Height
        {
            set
            {
                if (value < 300)
                {
                    m_Height = 300;
                }
                else
                {
                    m_Height = value;
                }
            }
            get
            {
                return m_Height;
            }
        }

        public float XSlice
        {
            set
            {
                m_XSlice = value;
            }
            get
            {
                return m_XSlice;
            }
        }

        public float YSlice
        {
            set
            {
                m_YSlice = value;
            }
            get
            {
                return m_YSlice;
            }
        }

        public float YSliceValue
        {
            set
            {
                m_YSliceValue = value;
            }
            get
            {
                return m_YSliceValue;
            }
        }

        public float YSliceBegin
        {
            set
            {
                m_YSliceBegin = value;
            }
            get
            {
                return m_YSliceBegin;
            }
        }

        public int XSliceValue
        {
            set
            {
                m_XSliceValue = value;
            }
            get
            {
                return m_XSliceValue;
            }
        }

        public long XSliceBegin
        {
            set
            {
                m_XSliceBegin = value;
            }
            get
            {
                return m_XSliceBegin;
            }
        }

        public float Tension
        {
            set
            {
                if (value < 0.0f && value > 1.0f)
                {
                    m_Tension = 0.5f;
                }
                else
                {
                    m_Tension = value;
                }
            }
            get
            {
                return m_Tension;
            }
        }

        public string Title
        {
            set
            {
                m_Title = value;
            }
            get
            {
                return m_Title;
            }
        }

        public string Unit
        {
            set
            {
                m_Unit = value;
            }
            get
            {
                return m_Unit;
            }
        }

        public string[] Keys
        {
            set
            {
                m_Keys = value;
            }
            get
            {
                return m_Keys;
            }
        }

        public long[] KeyValues
        {
            set
            {
                m_KeyValues = value;
            }
            get
            {
                return m_KeyValues;
            }
        }

        public float[] Values
        {
            set
            {
                m_Values = value;
            }
            get
            {
                return m_Values;
            }
        }

        public Color BgColor
        {
            set
            {
                m_BgColor = value;
            }
            get
            {
                return m_BgColor;
            }
        }

        public Color TextColor
        {
            set
            {
                m_TextColor = value;
            }
            get
            {
                return m_TextColor;
            }
        }

        public Color BorderColor
        {
            set
            {
                m_BorderColor = value;
            }
            get
            {
                return m_BorderColor;
            }
        }

        public Color AxisColor
        {
            set
            {
                m_AxisColor = value;
            }
            get
            {
                return m_AxisColor;
            }
        }

        public string XAxisText
        {
            set
            {
                m_XAxisText = value;
            }
            get
            {
                return m_XAxisText;
            }
        }

        public string YAxisText
        {
            set
            {
                m_YAxisText = value;
            }
            get
            {
                return m_YAxisText;
            }
        }

        public string CurveName
        {
            get
            {
                return m_CurveName;
            }
            set
            {
                m_CurveName = value;
            }

        }

        public float CurveWidth
        {
            get
            {
                return m_CurveWidth;
            }
            set
            {
                m_CurveWidth = value;
            }
        }

        public Color AxisTextColor
        {
            set
            {
                m_AxisTextColor = value;
            }
            get
            {
                return m_AxisTextColor;
            }
        }

        public Color SliceTextColor
        {
            set
            {
                m_SliceTextColor = value;
            }
            get
            {
                return m_SliceTextColor;
            }
        }

        public Color SliceColor
        {
            set
            {
                m_SliceColor = value;
            }
            get
            {
                return m_SliceColor;
            }
        }

        public Color CurveColor
        {
            set
            {
                m_CurveColor = value;
            }
            get
            {
                return m_CurveColor;
            }
        }

        public CurveOption CO
        {
            set
            {
                m_CO = value;
            }
            get
            {
                return m_CO;
            }
        }
        #endregion

        //生成图像并返回bmp图像对象
        //public Bitmap CreateImage()
        //{
        //    InitializeGraph();

        //    DrawContent(ref objGraphics);

        //    return objBitmap;
        //}

        //初始化和填充图像区域，画出边框，初始标题
        public void InitializeGraph()
        {

            //根据给定的高度和宽度创建一个位图图像
            objBitmap = new Bitmap(Width, Height);

            //从指定的 objBitmap 对象创建 objGraphics 对象 (即在objBitmap对象中画图)
            objGraphics = Graphics.FromImage(objBitmap);

            //根据给定颜色(LightGray)填充图像的矩形区域 (背景)
            objGraphics.DrawRectangle(new Pen(BorderColor, 1), 0, 0, Width, Height);
            objGraphics.FillRectangle(new SolidBrush(BgColor), 1, 1, Width - 2, Height - 2);

            //画X轴,pen,x1,y1,x2,y2 注意图像的原始X轴和Y轴计算是以左上角为原点，向右和向下计算的
            objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor), 1), 50, Height - 100, Width, Height - 100);

            //画Y轴,pen,x1,y1,x2,y2
            objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor), 1), 50, Height - 100, 50, 50);

            //初始化轴线说明文字
            //SetAxisText();

            //初始化存储曲线名称的坐标
            m_TempCurveName = new Point(250, Height - 75);

            //初始化X轴上的刻度和文字
            SetXAxis(ref objGraphics);

            //初始化Y轴上的刻度和文字
            SetYAxis(ref objGraphics);

            //初始化标题
            CreateTitle(ref objGraphics);
        }

        //横纵轴说明文字，暂未使用
        public void SetAxisText()
        {
            objGraphics.DrawString(XAxisText, new Font("宋体", 10), new SolidBrush(AxisTextColor), Width / 2 - 50, Height - 75);

            int X = 25;
            int Y = (Height / 2) - 50;
            for (int i = 0; i < YAxisText.Length; i++)
            {
                objGraphics.DrawString(YAxisText[i].ToString(), new Font("宋体", 10), new SolidBrush(AxisTextColor), X, Y);
                Y += 15;
            }
        }

        public void SetCurveName(int index)
        {
            m_TempCurveName.X = m_TempCurveName.X + (10 + 5 + 10 + 15 * CurveName.Length);// *index;
            objGraphics.DrawLine(new Pen(CurveColor, CurveWidth), m_TempCurveName, new Point(m_TempCurveName.X + 10, m_TempCurveName.Y));
            objGraphics.DrawString(CurveName, new Font("宋体", 10), new SolidBrush(TextColor), new Point(m_TempCurveName.X + 15, m_TempCurveName.Y - 5));
        }

        private void SetXAxis(ref Graphics objGraphics)
        {
            //横轴原点坐标的x值
            int x1 = 50;
            //横轴刻度线的两个y值
            int y1 = Height - 105;
            int y2 = Height - 100;
            string tempDate = "";
            //计算需要画的刻度线的数量
            int iWidth = (int)((Width - 100) / XSlice);
            //将横轴原点所表示的时间拆开成日期和时分秒分别绘制
            DateTime dt = new DateTime(XSliceBegin * 10000000, System.DateTimeKind.Local);
            TimeSpan ts = dt.TimeOfDay;
            tempDate = ts.ToString();
            objGraphics.DrawString(dt.Date.ToShortDateString(), new Font("宋体", 16), new SolidBrush(SliceTextColor), x1, y2 + 25);
            objGraphics.DrawString(tempDate, new Font("宋体", 8), new SolidBrush(SliceTextColor), x1 - 22, y2 + 3);
            //绘制刻度线以及刻度
            for (int i = 0; i <= iWidth; i++)
            {
                //刻度线
                objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor)), x1 + (i + 1) * XSlice, y1, x1 + (i + 1) * XSlice, y2);
                //计算该刻度线表示的时分秒刻度值
                dt = new DateTime(XSliceBegin * 10000000 + (long)(i + 1) * XSliceValue * 10000000, System.DateTimeKind.Unspecified);
                ts = dt.TimeOfDay;
                tempDate = ts.ToString();
                //刻度
                objGraphics.DrawString(tempDate, new Font("宋体", 8), new SolidBrush(SliceTextColor), x1 + (i + 1) * XSlice - 22, y2 + 3);
                //出界则推出
                if (x1 + i * XSlice > Width)
                {
                    break;
                }
            }
        }

        private void SetYAxis(ref Graphics objGraphics)
        {
            //纵轴刻度线的两个x值
            int x1 = 50;
            int x2 = 55;
            //纵轴原点的y值
            int y1 = Height - 100;
            //计算纵轴的刻度数量（目前定为10个）
            int iHeight = 10;
            //绘制原点的刻度
            objGraphics.DrawString(YSliceBegin.ToString(), new Font("宋体", 8), new SolidBrush(SliceTextColor), 20, y1 - 5);
            //绘制刻度线以及刻度
            for (int i = 0; i < iHeight; i++)
            {
                //刻度线
                objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor)), x1, y1 - (i + 1) * YSlice, x2, y1 - (i + 1) * YSlice);
                //刻度
                objGraphics.DrawString(Convert.ToString(Math.Round((YSliceValue * (i + 1) + YSliceBegin), 1)), new Font("宋体", 8), new SolidBrush(SliceTextColor), 20, y1 - 5 - (i + 1) * YSlice);

            }
        }

        //绘制曲线
        public void DrawContent()
        {
            if (Keys.Length == Values.Length && Keys.Length != 1)
            {
                Pen CurvePen = new Pen(CurveColor, CurveWidth);
                PointF[] CurvePointF = new PointF[Keys.Length];
                float keyvalues = 0;
                float values = 0;
                for (int i = 0; i < Keys.Length; i++)
                {
                    keyvalues = 50 + (KeyValues[i] - XSliceBegin) * (XSlice / XSliceValue);
                    values = Height - 100 - (Values[i] - YSliceBegin) * (YSlice / YSliceValue);
                    CurvePointF[i] = new PointF(keyvalues, values);
                }
                objGraphics.DrawCurve(CurvePen, CurvePointF, Tension);
            }
            else
            {
                objGraphics.DrawString("Error!The length of Keys and Values must be same and greater than 1!", new Font("宋体", 16), new SolidBrush(TextColor), new Point(150, Height / 2));
            }
        }

        //初始化标题
        private void CreateTitle(ref Graphics objGraphics)
        {
            objGraphics.DrawString(Title, new Font("宋体", 16), new SolidBrush(TextColor), new Point(Width / 2 - 60, 5));
        }
    }

    /// <summary>
    /// 曲线绘制选项
    /// </summary>
    public enum CurveOption
    {
        /// <summary>
        /// 自定义曲线
        /// </summary>
        ByCustom,
        /// <summary>
        /// 日曲线
        /// </summary>
        ByDay,
        /// <summary>
        /// 月曲线
        /// </summary>
        ByMonth,
        /// <summary>
        /// 年曲线
        /// </summary>
        ByYear
    }
}
